package org.dingyom.org.service.impl;

import org.apache.logging.log4j.util.Strings;
import org.dingyom.basics.constants.BaseConstants;
import org.dingyom.basics.service.IBaiduAiService;
import org.dingyom.basics.service.IEmailService;
import org.dingyom.basics.util.AjaxResult;
import org.dingyom.basics.util.RedisUtils;
import org.dingyom.org.domain.Employee;
import org.dingyom.org.domain.Shop;
import org.dingyom.org.domain.ShopAuditLog;
import org.dingyom.org.dto.ShopActiveDto;
import org.dingyom.org.mapper.EmployeeMapper;
import org.dingyom.org.mapper.ShopAuditLogMapper;
import org.dingyom.org.mapper.ShopMapper;
import org.dingyom.org.service.IEmployeeService;
import org.dingyom.org.service.IShopService;
import org.dingyom.basics.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dingyom
 * @since 2022-09-01
 */
@Service
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    ShopMapper shopMapper;
    @Autowired
    EmployeeMapper employeeMapper;
    @Autowired
    IEmployeeService employeeService;
    @Autowired
    ShopAuditLogMapper shopAuditLogMapper;
    @Autowired
    IBaiduAiService baiduAiService;

    @Autowired
    IEmailService emailService;
    /**
     * 店铺入驻业务
     * @param shop
     */
    @Override
    @Transactional
    public void settlement(Shop shop) {
        /*校验*/
        validate(shop);

        /*如果管理员原来就有店铺*/
        //方案1（采纳） 直接使用原来的管理员信息
        //方案2 不让入驻 登陆进后台进行添加店铺
        Employee employee = employeeMapper.loadByUsername(shop.getAdmin().getUsername());
        if (employee != null) {//管理员存在了 就直接用这个管理员
            shop.setAdminId(employee.getId());
        }else {
            //不存在 就保存管理员 返回自增id
            Employee admin = shop.getAdmin();
            employeeService.add(admin);
            //返回的自增id放入shop的adminid中
            shop.setAdminId(admin.getId());
        }
        /*保存商铺信息*/
        shop.setRegisterTime(new Date());
        shopMapper.save(shop);

        /*自动审核 会根据审核结果修改 店铺状态 并添加 审核日志*/
        //审核的内容 --文本审核 店铺名字和地址
        String auditTest = shop.getName() + "" + shop.getAddress();
        AjaxResult ajaxResult = baiduAiService.audit(auditTest, null, null);
        if (ajaxResult.isSuccess()){//审核通过
            //店铺状态改为以审核通过 待激活
            shop.setState(BaseConstants.Shop.STATE_WAIT_ACTIVE);
        }else{//审核不通过
            //店铺状态改为驳回
            shop.setState(BaseConstants.Shop.STATE_REJECT_AUDIT);
        }
        shopMapper.update(shop);//修改店铺信息

        //审核日志
        ShopAuditLog shopAuditLog = new ShopAuditLog();
        shopAuditLog.setShopId(shop.getId());//审核店铺
        //审核人 自动审核没有审核人
        shopAuditLog.setAuditTime(new Date());//审核时间
        //审核内容
        shopAuditLog.setNote(
                ajaxResult.isSuccess()?"审核通过！":"审核失败,"+ajaxResult.getMessage()
        );
        shopAuditLogMapper.save(shopAuditLog);

        //审核通过的话 就需要进行邮箱激活
        if(ajaxResult.isSuccess()){
            //生成激活码
            String activeId = UUID.randomUUID().toString();
            /*激活码需要保存进redis中 同时还要通过邮箱发给给店铺管理员*/
            //将店铺id作为key 激活码作为value
            RedisUtils redis = RedisUtils.INSTANCE;
            redis.set(Long.toString(shop.getId()), activeId, 1800);//30分钟 就是1800秒
            //发送邮件给管理员
            emailService.send(shop.getId(),activeId,shop.getAdmin().getEmail());
        }
    }

    @Override
    @Transactional
    public void active(ShopActiveDto dto) {
        RedisUtils redis = RedisUtils.INSTANCE;
        String uid = redis.get(Long.toString(dto.getShopId()));
        if (uid == null) {//激活码已经过期了 或者其他异常
            throw new RuntimeException("激活码过期，或异常，请重新输入");
        }
        if(!uid.equals(dto.getActiveId())){//输入的激活码与redis的不匹配
            throw new RuntimeException("激活码输入错误或已过期");
        }else {//匹配上了就激活成功
            //查询出店铺信息
            Shop shop = shopMapper.loadById(dto.getShopId());
            shop.setState(BaseConstants.Shop.STATE_ACTIVE_SUCCESS);//修改店铺状态
            shopMapper.update(shop);
        }
    }

    @Override
    @Transactional
    public void passAudit(Shop shop) {
        /*审核通过 修改店铺状态 审核日志 发送激活邮件*/
        shop.setState(BaseConstants.Shop.STATE_WAIT_ACTIVE);
        shop.setAdminId(shop.getAdmin().getId());
        shopMapper.update(shop);

        //审核日志
        ShopAuditLog shopAuditLog = new ShopAuditLog();
        shopAuditLog.setShopId(shop.getId());//审核店铺
        //审核人 就是当前登陆用户 TODO
//        shopAuditLog.setAuditId();
        shopAuditLog.setAuditTime(new Date());//审核时间
        //审核内容
        shopAuditLog.setNote("审核通过！");
        shopAuditLogMapper.save(shopAuditLog);

        //发送激活邮件
        //生成激活码
        String activeId = UUID.randomUUID().toString();
        /*激活码需要保存进redis中 同时还要通过邮箱发给给店铺管理员*/
        //将店铺id作为key 激活码作为value
        RedisUtils redis = RedisUtils.INSTANCE;
        redis.set(Long.toString(shop.getId()), activeId, 1800);//30分钟 就是1800秒
        //发送邮件给管理员
        emailService.send(shop.getId(),activeId,shop.getAdmin().getEmail());
    }

    @Override
    @Transactional
    public void disagreeAudit(Shop shop) {
        /*审核驳回 修改店铺状态 审核日志*/
        shop.setState(BaseConstants.Shop.STATE_REJECT_AUDIT);
        shop.setAdminId(shop.getAdmin().getId());
        shopMapper.update(shop);

        //审核日志
        ShopAuditLog shopAuditLog = new ShopAuditLog();
        shopAuditLog.setShopId(shop.getId());//审核店铺
        //审核人 就是当前登陆用户 TODO
//        shopAuditLog.setAuditId();
        shopAuditLog.setAuditTime(new Date());//审核时间
        //审核内容
        shopAuditLog.setNote("审核失败！");
        shopAuditLogMapper.save(shopAuditLog);
    }

    /**
     * 批量激活 由管理员操作
     * @param ids
     */
    @Override
    @Transactional
    public void batchAct(List<Long> ids) {
        List<Shop> shops = shopMapper.loadBatch(ids);//查询出shop信息
        shops.forEach(shop->{
            //通过shop中的adminId查询出管理员信息
            Employee admin = employeeMapper.loadById(shop.getAdminId());

            //发送激活邮件
            //生成激活码
            String activeId = UUID.randomUUID().toString();
            /*激活码需要保存进redis中 同时还要通过邮箱发给给店铺管理员*/
            //将店铺id作为key 激活码作为value
            RedisUtils redis = RedisUtils.INSTANCE;
            redis.set(Long.toString(shop.getId()), activeId, 1800);//30分钟 就是1800秒
            //发送邮件给管理员
            emailService.send(shop.getId(),activeId,admin.getEmail());
        });
    }

    /**
     * 校验
     * @param shop
     */
    private void validate(Shop shop) {
        //null校验
        if (shop == null) {
            throw new RuntimeException("系统错误！请输入相关信息后再操作");
        }
        if (Strings.isEmpty(shop.getName())) {//店铺名
            throw new RuntimeException("系统错误！请输入相关信息后再操作");
        }
        if (shop.getAdmin() == null) {//管理员
            throw new RuntimeException("系统错误！请输入相关信息后再操作");
        }
        //两次密码比对
        if (shop.getAdmin().getComfirmPassword() == null|| shop.getAdmin().getPassword()==null
                || !shop.getAdmin().getPassword().equals(shop.getAdmin().getComfirmPassword())) {
            throw new RuntimeException("系统错误！请输入相关信息后再操作");
        }
        //店铺是否存在
        Shop byName = shopMapper.loadByName(shop.getName());
        if (byName != null) {
            throw new RuntimeException("系统错误！该店铺已经存在");
        }
    }
}
